﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MethodWorx.CMS.Content;
using MethodWorx.CMS.TemplateLanguage.Properties;
using MethodWorx.CMS.Web;
using System.Xml;
using MethodWorx.CMS.TemplateLanguage.Design;

namespace MethodWorx.CMS.TemplateLanguage.Parsers
{
    public class PagePropertyParser : IParser, IDesignable, IMetaParser, IEditable
    {
        [Property]
        public string Tag { get; set; }
        [PageTemplateProperty]
        public string Template { get; set; }
        [PageTemplatePropertyPropertyAttribute("Template", Alias = "Name")]
        public string PropertyName { get; set; }
        [Property]
        public bool Editable { get; set; }
        [Property(Alias = "Class")]
        public string CssClass { get; set; }
        [Property(Alias = "DefaultValue")]
        public string DefaultValue { get; set; }

        public object Parse(CmsRequestContext context, IEnumerable<object> stack, Dictionary<string, object> parameters)
        {
            if (!string.IsNullOrEmpty(this.PropertyName))
            {
                var page = stack.OfType<MethodWorx.CMS.Content.Page>().FirstOrDefault();
                if (page == null)
                    throw new Exception("No page on the stack");
                else
                {
                    //
                    //  ok, find the property
                    PageProperty found = null;
                    

                    if(context.Preview)
                        found = page.Properties.FirstOrDefault(p => p.Name.ToLower() == this.PropertyName.ToLower());
                    else
                        found = page.PublishedProperties.FirstOrDefault(p => p.Name.ToLower() == this.PropertyName.ToLower());

                    if (found != null && found.Value != null)
                    {
                        if (found.Value.IsNull() || found.Value.IsEmpty())
                            return null;

                        return GetNodeValue(found.Value, parameters);
                    }
                    else
                    {
                        if (this.PropertyName.ToLower() == "datepublished")
                            return GetNodeValue(page.DatePublished, parameters);
                        else if (this.PropertyName.ToLower() == "datecreated")
                            return GetNodeValue(page.DateCreated, parameters);
                        else if (this.PropertyName.ToLower() == "name")
                            return GetNodeValue(page.Name, parameters);
                        else if (this.PropertyName.ToLower() == "createdby")
                            return GetNodeValue(page.CreatedBy.Username, parameters);
                    }
                }
            }

            return null;
        }
        public object GetNodeValue(object property, Dictionary<string, object> parameters)
        {
            if (string.IsNullOrEmpty(this.Tag))
            {
                return property;
            }
            else
            {
                //var val = tag + property.Value.ToString() + "</tag>";
                var result = new HtmlResult();
                result.SetTag(this.Tag);
                result.Content = property;
                foreach (string parameter in parameters.Keys)
                {
                    result.AddAttribute(parameter, parameters[parameter].ToString());
                }
                return result;
            }
        }

   

        public string Name
        {
            get { return "Property"; }
        }

        public string Namespace
        {
            get { return "Page"; }
        }

        public void Design(IDesigner designer)
        {
            if (!string.IsNullOrEmpty(this.Tag))
            {
                designer.AddControl("Page:Property")
                    .AddContentBeforeChildren("<" + this.Tag + " class=\"" + (this.CssClass ?? "") + "\">" +
                                              (this.DefaultValue ?? "") + " (" + (this.Template ?? "") + ":" + (this.PropertyName ?? "") + ")")
                    .AddContentAfterChildren("</" + this.Tag + ">");

            }
            else
            {
                designer.AddControl("Page:Property")
                    .AddContentBeforeChildren("<pageProperty>" + this.DefaultValue + " (" + this.Template + ":" + this.PropertyName + ")</pageProperty>");
            }
        }


        public string GetDescription()
        {
            return "Retrieve a property value, from the current page";
        }


        public ParserMetaParameter[] GetParameters(Stack<object> stack, ParserMetaParameter[] parameters)
        {
            return parameters;
        }

        public void Edit(IEditor editor)
        {
            var page = editor.Stack.OfType<MethodWorx.CMS.Content.Page>().FirstOrDefault();
            if (page != null)
            {
                editor.AddEditor(this.PropertyName, page);
            }
        }
    }
}
